
package org.apache.solr.analysis;

import java.io.Reader;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.util.CharFilterFactory;
import org.apache.lucene.analysis.util.TokenFilterFactory;
import org.apache.lucene.analysis.util.TokenizerFactory;

/**
 * An analyzer that uses a tokenizer and a list of token filters to
 * create a TokenStream.
 */
public final class TokenizerChain extends SolrAnalyzer {

    final private CharFilterFactory[] charFilters;
    final private TokenizerFactory tokenizer;
    final private TokenFilterFactory[] filters;

    public TokenizerChain(TokenizerFactory tokenizer, TokenFilterFactory[] filters) {
        this(null, tokenizer, filters);
    }

    public TokenizerChain(CharFilterFactory[] charFilters, TokenizerFactory tokenizer, TokenFilterFactory[] filters) {
        this.charFilters = charFilters;
        this.tokenizer = tokenizer;
        this.filters = filters;
    }

    public CharFilterFactory[] getCharFilterFactories() {
        return charFilters;
    }

    public TokenizerFactory getTokenizerFactory() {
        return tokenizer;
    }

    public TokenFilterFactory[] getTokenFilterFactories() {
        return filters;
    }

    @Override
    public Reader initReader(String fieldName, Reader reader) {
        
        if(charFilters != null && charFilters.length > 0) {
            Reader cs = reader;
            for(CharFilterFactory charFilter : charFilters) {
                cs = charFilter.create(cs);
            }
            reader = cs;
        }
        return reader;
    }

    @Override
    protected TokenStreamComponents createComponents(String fieldName, Reader aReader) {

        Tokenizer tk = tokenizer.create(aReader);
        TokenStream ts = tk;
        for(TokenFilterFactory filter : filters) {
            ts = filter.create(ts);
        }
        return new TokenStreamComponents(tk, ts);
    }

    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder("TokenizerChain(");
        for(CharFilterFactory filter : charFilters) {
            sb.append(filter);
            sb.append(", ");
        }
        sb.append(tokenizer);
        for(TokenFilterFactory filter : filters) {
            sb.append(", ");
            sb.append(filter);
        }
        sb.append(')');

        return sb.toString();
    }
}
